<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  
  
  <title>LinkLiao610 Blog</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <meta name="description" content="分享一些IC设计相关的知识">
<meta property="og:type" content="website">
<meta property="og:title" content="LinkLiao610 Blog">
<meta property="og:url" content="https://linkliao610.gitee.io/index.html">
<meta property="og:site_name" content="LinkLiao610 Blog">
<meta property="og:description" content="分享一些IC设计相关的知识">
<meta property="og:locale">
<meta property="article:author" content="LinkLiao">
<meta name="twitter:card" content="summary">
  
    <link rel="alternate" href="/atom.xml" title="LinkLiao610 Blog" type="application/atom+xml">
  
  
    <link rel="shortcut icon" href="/favicon.png">
  
  
  
<link rel="stylesheet" href="/css/style.css">

  
    
<link rel="stylesheet" href="/fancybox/jquery.fancybox.min.css">

  
  
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/fork-awesome@1.2.0/css/fork-awesome.min.css">

<meta name="generator" content="Hexo 7.3.0"></head>

<body>
  <div id="container">
    <div id="wrap">
      <header id="header">
  <div id="banner"></div>
  <div id="header-outer" class="outer">
    <div id="header-title" class="inner">
      <h1 id="logo-wrap">
        <a href="/" id="logo">LinkLiao610 Blog</a>
      </h1>
      
        <h2 id="subtitle-wrap">
          <a href="/" id="subtitle">LinkLiao610</a>
        </h2>
      
    </div>
    <div id="header-inner" class="inner">
      <nav id="main-nav">
        <a id="main-nav-toggle" class="nav-icon"><span class="fa fa-bars"></span></a>
        
          <a class="main-nav-link" href="/">Home</a>
        
          <a class="main-nav-link" href="/archives">Archives</a>
        
      </nav>
      <nav id="sub-nav">
        
        
          <a class="nav-icon" href="/atom.xml" title="RSS Feed"><span class="fa fa-rss"></span></a>
        
        <a class="nav-icon nav-search-btn" title="Search"><span class="fa fa-search"></span></a>
      </nav>
      <div id="search-form-wrap">
        <form action="//google.com/search" method="get" accept-charset="UTF-8" class="search-form"><input type="search" name="q" class="search-form-input" placeholder="Search"><button type="submit" class="search-form-submit">&#xF002;</button><input type="hidden" name="sitesearch" value="https://LinkLiao610.gitee.io"></form>
      </div>
    </div>
  </div>
</header>

      <div class="outer">
        <section id="main">
  
    <article id="post-Protocol-Series-SPI-0" class="h-entry article article-type-post" itemprop="blogPost" itemscope itemtype="https://schema.org/BlogPosting">
  <div class="article-meta">
    <a href="/2025/03/12/Protocol-Series-SPI-0/" class="article-date">
  <time class="dt-published" datetime="2025-03-12T02:12:24.000Z" itemprop="datePublished">2025-03-12</time>
</a>
    
  <div class="article-category">
    <a class="article-category-link" href="/categories/Protocol/">Protocol</a>
  </div>

  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="p-name article-title" href="/2025/03/12/Protocol-Series-SPI-0/">SPI从收发器电路设计</a>
    </h1>
  

      </header>
    
    <div class="e-content article-entry" itemprop="articleBody">
      
        <h1 id="1-SPI-协议介绍"><a href="#1-SPI-协议介绍" class="headerlink" title="1.SPI 协议介绍"></a>1.SPI 协议介绍</h1><p>SPI（Serial Peripheral Interface，串行外设接口）是一种高速、全双工、同步的串行通信协议，由摩托罗拉公司在20世纪80年代中期开发，后成为行业标准，广泛应用于微控制器与外围设备之间的短距离通信。基本原理SPI通信采用主从模式，由一个主设备和一个或多个从设备组成。主设备负责控制通信过程，包括生成时钟信号、选择从设备以及发送和接收数据。从设备则根据主设备的控制信号进行响应。SPI通信通常需要至少4根线：</p>
<p>• <strong>CS#（Chip Select&#x2F;Slave Select）</strong>：从设备选择信号线，用于主设备选择与其通信的从设备。<br>• <strong>SCK（Serial Clock）</strong>：时钟信号线，由主设备产生，用于同步数据传输。<br>• <strong>MOSI（Master Output, Slave Input）</strong>：主设备输出、从设备输入的数据线。<br>• <strong>MISO（Master Input, Slave Output）</strong>：主设备输入、从设备输出的数据线。</p>
<p>工作模式SPI协议定义了四种工作模式，由时钟极性（CPOL）和时钟相位（CPHA）两个参数决定：</p>
<ul>
<li><strong>模式0（CPOL&#x3D;0, CPHA&#x3D;0）</strong>：时钟空闲状态为低电平，数据在时钟的第一个跳变沿采样。</li>
<li><strong>模式1（CPOL&#x3D;0, CPHA&#x3D;1）</strong>：时钟空闲状态为低电平，数据在时钟的第二个跳变沿采样。</li>
<li><strong>模式2（CPOL&#x3D;1, CPHA&#x3D;0）</strong>：时钟空闲状态为高电平，数据在时钟的第一个跳变沿采样。</li>
<li><strong>模式3（CPOL&#x3D;1, CPHA&#x3D;1）</strong>：时钟空闲状态为高电平，数据在时钟的第二个跳变沿采样。</li>
</ul>
<p>优势与特点</p>
<p>SPI协议具有以下显著优势</p>
<ul>
<li><strong>高速传输</strong>：支持较高的数据传输速率，适合对实时性要求较高的应用场景。</li>
<li><strong>全双工通信</strong>：主设备和从设备可以同时发送和接收数据，提高了通信效率。</li>
<li><strong>硬件接口简单</strong>：仅需少量引脚即可实现设备间通信，降低了硬件成本和复杂度。</li>
<li><strong>灵活性高</strong>：支持多种工作模式，可根据不同设备的需求进行配置。</li>
</ul>
<h1 id="2-QSPI-介绍"><a href="#2-QSPI-介绍" class="headerlink" title="2. QSPI 介绍"></a>2. QSPI 介绍</h1><p>QSPI（Quad Serial Peripheral Interface，四通道串行外设接口）是一种基于SPI协议的高速扩展接口，通过增加数据线数量和优化传输机制，显著提升了数据传输速率，广泛应用于需要高速数据交换的场景。</p>
<p>QSPI的核心特性</p>
<ol>
<li>信号线定义</li>
</ol>
<ul>
<li><strong>SCLK（时钟信号）</strong>：由主设备生成，控制数据传输的时序。</li>
<li><strong>CS#（片选信号）</strong>：用于选择从设备。</li>
<li><strong>IO0IO3（数据线）</strong>：四条数据线，用于并行传输数据。传统SPI仅使用MOSI和MISO两条数据线，而QSPI通过四条数据线实现更高的传输效率。</li>
</ul>
<ol start="2">
<li>工作模式</li>
</ol>
<ul>
<li><strong>单线模式（Standard SPI）</strong>：与传统SPI兼容，仅使用单线传输。</li>
<li><strong>双线模式（Dual SPI）</strong>：使用两条数据线（IO0和IO1）进行数据传输。</li>
<li><strong>四线模式（Quad SPI）</strong>：使用四条数据线（IO0IO3）并行传输，每个时钟周期可传输4位数据。</li>
<li><strong>DDR模式（Double Data Rate）</strong>：在时钟的上升沿和下降沿均传输数据，进一步倍增速率。</li>
</ul>
<ol start="3">
<li>性能优势</li>
</ol>
<ul>
<li><strong>传输速率</strong>：QSPI的理论带宽可达传统SPI的4倍（四线模式）或8倍（四线模式+DDR）。例如，在100 MHz时钟频率下，QSPI四线模式的理论带宽为400 Mbps，DDR模式下可达800 Mbps。</li>
<li><strong>协议优化</strong>：支持内存映射模式（XIP，Execute-In-Place），允许CPU直接从外部Flash读取代码，无需先加载到RAM，从而提高启动和运行效率。</li>
</ul>
<h1 id="3-SPI-从收发器电路设计规格"><a href="#3-SPI-从收发器电路设计规格" class="headerlink" title="3.SPI 从收发器电路设计规格"></a>3.SPI 从收发器电路设计规格</h1><p>本文描述的SPI 从收发器电路设计规格如下：</p>
<ul>
<li><strong>SPI 运行频率</strong>：ASIC下100MHz+, FPGA下50MHz+</li>
<li><strong>SPI 协议模式</strong>：支持模式0和模式3(模式1和模式2暂未测试)</li>
<li><strong>QSPI 工作模式</strong>：支持单线模式+双线模式+四线模式</li>
<li><strong>应用场景</strong>： 支持类似QSPI Flash芯片中，SPI 从设备的功能</li>
</ul>
<h1 id="4-SPI-从收发器设计思路"><a href="#4-SPI-从收发器设计思路" class="headerlink" title="4.SPI 从收发器设计思路"></a>4.SPI 从收发器设计思路</h1><p>SPI 模式0和模式3的时序图如下:</p>
<p><img src="/2025/03/12/Protocol-Series-SPI-0/SPI_Inst_READ.bmp" alt="SPI_Inst_Read"></p>
<p>对于SPI 从设备而言，SPI 的时钟来自于SPI主设备，当CS#拉高时，时钟SCK不翻转，因此需要使用CS#作为部分寄存器的异步复位信号。</p>
<p>模式0和模式3的数据均在时钟SCK上升沿接收数据，SCK的下降沿发送数据，因此，收发有半个SCK时钟周期的相位差，其中， 模式0先收后发，模式3先发后收。</p>
<p>SPI 从收发器会将时钟SCK拆分成1个数据发送时钟spi_sck_tx 和1个数据接收时钟spi_sck_rx.</p>
<p>SPI 从收发器以字节为单位进行数据收发，对于CS#拉低后的第一个字节通信，默认从设备只接收数据，不发送数据。</p>
<p>对于SPI 从收发器，需要确保每个字节的收和发都完成后才能开始下一个字节的收和发。也就是说，不管是模式0还是模式3，<strong>每个字节的发送都可以在接收完上一个字节后的半个周期后进行</strong>。</p>
<p>因此，SPI 从收发器电路使用接收时钟spi_sck_rx来同步数据的接收和发送逻辑，最终，对于数据发送，只需要在数据输出到端口前，使用发送时钟spi_sck_tx驱动的寄存器对发送数据延迟半个SCK时钟周期</p>
<h1 id="5-SPI-从收发器电路"><a href="#5-SPI-从收发器电路" class="headerlink" title="5. SPI 从收发器电路"></a>5. SPI 从收发器电路</h1><p>SPI从收发器电路代码如下:</p>
<figure class="highlight verilog"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br><span class="line">274</span><br><span class="line">275</span><br><span class="line">276</span><br><span class="line">277</span><br><span class="line">278</span><br><span class="line">279</span><br><span class="line">280</span><br><span class="line">281</span><br><span class="line">282</span><br><span class="line">283</span><br><span class="line">284</span><br><span class="line">285</span><br><span class="line">286</span><br><span class="line">287</span><br><span class="line">288</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">module</span> SpiSlvTrx (</span><br><span class="line">    <span class="keyword">input</span>  <span class="keyword">wire</span>          rstn,</span><br><span class="line">    <span class="comment">//SPI Port</span></span><br><span class="line">    <span class="keyword">input</span>  <span class="keyword">wire</span>          spi_sck_tx,</span><br><span class="line">    <span class="keyword">input</span>  <span class="keyword">wire</span>          spi_sck_rx,</span><br><span class="line">    <span class="keyword">input</span>  <span class="keyword">wire</span>          spi_csn_in,</span><br><span class="line">    <span class="keyword">output</span> <span class="keyword">wire</span>          spi_mosi_out, <span class="comment">//SIO0</span></span><br><span class="line">    <span class="keyword">output</span> <span class="keyword">wire</span>          spi_mosi_oe,</span><br><span class="line">    <span class="keyword">input</span>  <span class="keyword">wire</span>          spi_mosi_in,</span><br><span class="line">    <span class="keyword">output</span> <span class="keyword">wire</span>          spi_miso_out, <span class="comment">//SIO1</span></span><br><span class="line">    <span class="keyword">output</span> <span class="keyword">wire</span>          spi_miso_oe,</span><br><span class="line">    <span class="keyword">input</span>  <span class="keyword">wire</span>          spi_miso_in,</span><br><span class="line">    <span class="keyword">output</span> <span class="keyword">wire</span>          spi_wpn_out,  <span class="comment">//SIO2</span></span><br><span class="line">    <span class="keyword">output</span> <span class="keyword">wire</span>          spi_wpn_oe,</span><br><span class="line">    <span class="keyword">input</span>  <span class="keyword">wire</span>          spi_wpn_in,</span><br><span class="line">    <span class="keyword">output</span> <span class="keyword">wire</span>          spi_holdn_out, <span class="comment">//SIO3</span></span><br><span class="line">    <span class="keyword">output</span> <span class="keyword">wire</span>          spi_holdn_oe,</span><br><span class="line">    <span class="keyword">input</span>  <span class="keyword">wire</span>          spi_holdn_in,</span><br><span class="line"></span><br><span class="line">    <span class="keyword">input</span>  <span class="keyword">wire</span> [ <span class="number">1</span> : <span class="number">0</span>] ctrl_tx_speed,  <span class="comment">//控制发送数据的速率，1/2/4 bits</span></span><br><span class="line">    <span class="keyword">input</span>  <span class="keyword">wire</span> [ <span class="number">1</span> : <span class="number">0</span>] ctrl_rx_speed,  <span class="comment">//控制接收数据的速率，1/2/4 bits</span></span><br><span class="line">    <span class="keyword">output</span> <span class="keyword">wire</span>          stat_comm_acti, <span class="comment">//1&#x27;b1: 表示通信有效</span></span><br><span class="line">    <span class="keyword">output</span> <span class="keyword">wire</span>          stat_qpi_en,    <span class="comment">//1&#x27;b1: 表示处于QPI 模式</span></span><br><span class="line">    <span class="keyword">output</span> <span class="keyword">wire</span> [ <span class="number">7</span> : <span class="number">0</span>] stat_spi_cmd,   <span class="comment">//SPI 接收的第一个字节数据(即命令)</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">output</span> <span class="keyword">wire</span>          trx_tx_valid,   <span class="comment">//1&#x27;b1: 请求下个字节的发送数据</span></span><br><span class="line">    <span class="keyword">output</span> <span class="keyword">wire</span> [ <span class="number">3</span> : <span class="number">0</span>] trx_tx_bytes,   <span class="comment">//当前已发送的数据字节数</span></span><br><span class="line">    <span class="keyword">input</span>  <span class="keyword">wire</span> [ <span class="number">7</span> : <span class="number">0</span>] trx_tx_data,    <span class="comment">//下个字节要发送的数据</span></span><br><span class="line">    <span class="keyword">input</span>  <span class="keyword">wire</span>          trx_tx_ena,     <span class="comment">//下个字节是否将数据发送出去</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">output</span> <span class="keyword">wire</span>          trx_rx_valid,   <span class="comment">//1&#x27;b1: 表示已接收到一个字节的数据</span></span><br><span class="line">    <span class="keyword">output</span> <span class="keyword">wire</span> [ <span class="number">3</span> : <span class="number">0</span>] trx_rx_bytes,   <span class="comment">//当前已接收的数据字节数</span></span><br><span class="line">    <span class="keyword">output</span> <span class="keyword">wire</span> [ <span class="number">7</span> : <span class="number">0</span>] trx_rx_data,    <span class="comment">//当前接收的数据</span></span><br><span class="line"> </span><br><span class="line">    <span class="keyword">output</span> <span class="keyword">wire</span> [ <span class="number">2</span> : <span class="number">0</span>] spi_rx_bit_cnt, <span class="comment">//接收到一个字节里的bit 数</span></span><br><span class="line">    <span class="keyword">output</span> <span class="keyword">wire</span> [ <span class="number">7</span> : <span class="number">0</span>] spi_rx_data     <span class="comment">//接收移位寄存器的数据</span></span><br><span class="line"></span><br><span class="line">);</span><br><span class="line"></span><br><span class="line"><span class="keyword">localparam</span> [ <span class="number">1</span> : <span class="number">0</span>] spiSpeedSPI = <span class="number">2&#x27;b00</span>；</span><br><span class="line"><span class="keyword">localparam</span> [ <span class="number">1</span> : <span class="number">0</span>] spiSpeedDPI = <span class="number">2&#x27;b11</span>;</span><br><span class="line"><span class="keyword">localparam</span> [ <span class="number">1</span> : <span class="number">0</span>] spiSpeedQPI = <span class="number">2&#x27;b10</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">localparam</span> [ <span class="number">7</span> : <span class="number">0</span>] instEQIO    = <span class="number">8&#x27;h38</span>; <span class="comment">//进入QPI 模式的命令</span></span><br><span class="line"><span class="keyword">localparam</span> [ <span class="number">7</span> : <span class="number">0</span>] instRstQIO  = <span class="number">8&#x27;hFF</span>; <span class="comment">//推出QPI 模式的命令</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">wire</span>           rstn_spi;</span><br><span class="line"></span><br><span class="line"><span class="keyword">reg</span>            spi_mosi_out_ff;</span><br><span class="line"><span class="keyword">reg</span>            spi_mosi_oe_ff;</span><br><span class="line"><span class="keyword">reg</span>            spi_miso_out_ff;</span><br><span class="line"><span class="keyword">reg</span>            spi_miso_oe_ff;</span><br><span class="line"><span class="keyword">reg</span>            spi_wpn_out_ff;</span><br><span class="line"><span class="keyword">reg</span>            spi_wpn_oe_ff;</span><br><span class="line"><span class="keyword">reg</span>            spi_holdn_out_ff;</span><br><span class="line"><span class="keyword">reg</span>            spi_holdn_oe_ff;</span><br><span class="line"></span><br><span class="line"><span class="keyword">reg</span>            tx_enable_ff;</span><br><span class="line"><span class="keyword">reg</span>  [ <span class="number">7</span> :  <span class="number">0</span>] tx_shift_ff;</span><br><span class="line"><span class="keyword">wire</span>           tx_set_nx_byte;</span><br><span class="line"></span><br><span class="line"><span class="keyword">reg</span>  [ <span class="number">7</span> :  <span class="number">0</span>] rx_shift_ff;</span><br><span class="line"><span class="keyword">wire</span> [ <span class="number">7</span> :  <span class="number">0</span>] rx_shift_nx;</span><br><span class="line"><span class="keyword">reg</span>  [ <span class="number">2</span> :  <span class="number">0</span>] rx_cnt_ff;</span><br><span class="line"><span class="keyword">reg</span>  [ <span class="number">3</span> :  <span class="number">0</span>] rx_byte_cnt_ff;</span><br><span class="line"><span class="keyword">reg</span>  [ <span class="number">2</span> :  <span class="number">0</span>] rx_cnt_vld_mask;</span><br><span class="line"><span class="keyword">wire</span>           rx_byte_done;</span><br><span class="line"><span class="keyword">reg</span>            rx_byte_done_f1;</span><br><span class="line"><span class="keyword">reg</span>  [ <span class="number">7</span> :  <span class="number">0</span>] rx_data_f1;</span><br><span class="line"></span><br><span class="line"><span class="keyword">wire</span>           rx_first_byte;</span><br><span class="line"><span class="keyword">reg</span>  [ <span class="number">7</span> :  <span class="number">0</span>] rx_latch_cmd_ff;</span><br><span class="line"><span class="keyword">reg</span>            qpi_en_ff;</span><br><span class="line"><span class="keyword">reg</span>            comm_acti_ff;</span><br><span class="line"></span><br><span class="line"><span class="keyword">assign</span> rstn_spi = rstn &amp; !spi_csn_in;</span><br><span class="line"></span><br><span class="line"><span class="comment">//发送数据</span></span><br><span class="line"><span class="keyword">always</span> @(<span class="keyword">posedge</span> spi_sck_rx <span class="keyword">or</span> <span class="keyword">negedge</span> rstn_spi)</span><br><span class="line"><span class="keyword">begin</span></span><br><span class="line">    <span class="keyword">if</span>(!rstn_spi) <span class="keyword">begin</span></span><br><span class="line">        tx_enable_ff &lt;= <span class="number">1&#x27;h0</span>;</span><br><span class="line">        tx_shift_ff  &lt;= <span class="number">8&#x27;h00</span></span><br><span class="line">    <span class="keyword">end</span></span><br><span class="line">    <span class="keyword">else</span> <span class="keyword">if</span>(tx_set_nx_byte) <span class="keyword">begin</span></span><br><span class="line">        tx_enable_ff &lt;= trx_tx_ena;</span><br><span class="line">        tx_shift_ff  &lt;= trx_tx_data;</span><br><span class="line">    <span class="keyword">end</span></span><br><span class="line">    <span class="keyword">else</span> <span class="keyword">if</span>(ctrl_tx_speed == spiSpeedQPI) <span class="keyword">begin</span></span><br><span class="line">        tx_shift_ff  &lt;= &#123;tx_shift_ff[<span class="number">3</span>:<span class="number">0</span>], <span class="number">4&#x27;h0</span>&#125;;</span><br><span class="line">    <span class="keyword">end</span></span><br><span class="line">    <span class="keyword">else</span> <span class="keyword">if</span>(ctrl_tx_speed == spiSpeedDPI) <span class="keyword">begin</span></span><br><span class="line">        tx_shift_ff  &lt;= &#123;tx_shift_ff[<span class="number">5</span>:<span class="number">0</span>], <span class="number">2&#x27;h0</span>&#125;;</span><br><span class="line">    <span class="keyword">end</span></span><br><span class="line">    <span class="keyword">else</span> <span class="keyword">if</span>(ctrl_tx_speed == spiSpeedSPI) <span class="keyword">begin</span></span><br><span class="line">        tx_shift_ff  &lt;= &#123;tx_shift_ff[<span class="number">6</span>:<span class="number">0</span>], <span class="number">1&#x27;h0</span>&#125;;</span><br><span class="line">    <span class="keyword">end</span></span><br><span class="line"><span class="keyword">end</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">assign</span> tx_set_nx_byte = rx_byte_done;</span><br><span class="line"></span><br><span class="line"><span class="comment">//接收数据</span></span><br><span class="line"><span class="keyword">always</span> @(<span class="keyword">posedge</span> spi_sck_rx <span class="keyword">or</span> <span class="keyword">negedge</span> rstn_spi)</span><br><span class="line"><span class="keyword">begin</span></span><br><span class="line">    <span class="keyword">if</span>(!rstn_spi) <span class="keyword">begin</span></span><br><span class="line">        rx_cnt_ff &lt;= <span class="number">3&#x27;h0</span>;</span><br><span class="line">    <span class="keyword">end</span></span><br><span class="line">    <span class="keyword">else</span> <span class="keyword">if</span>(rx_byte_done) <span class="keyword">begin</span></span><br><span class="line">        rx_cnt_ff &lt;= <span class="number">3&#x27;h0</span>;</span><br><span class="line">    <span class="keyword">end</span></span><br><span class="line">    <span class="keyword">else</span> <span class="keyword">if</span>(ctrl_tx_speed == spiSpeedQPI) <span class="keyword">begin</span></span><br><span class="line">        rx_cnt_ff &lt;= rx_cnt_ff + <span class="number">3&#x27;h4</span>;</span><br><span class="line">    <span class="keyword">end</span></span><br><span class="line">    <span class="keyword">else</span> <span class="keyword">if</span>(ctrl_tx_speed == spiSpeedDPI) <span class="keyword">begin</span></span><br><span class="line">        rx_cnt_ff &lt;= rx_cnt_ff + <span class="number">3&#x27;h2</span>;</span><br><span class="line">    <span class="keyword">end</span></span><br><span class="line">    <span class="keyword">else</span> <span class="keyword">if</span>(ctrl_tx_speed == spiSpeedSPI) <span class="keyword">begin</span></span><br><span class="line">        rx_cnt_ff &lt;= rx_cnt_ff + <span class="number">3&#x27;h1</span>;</span><br><span class="line">    <span class="keyword">end</span></span><br><span class="line"><span class="keyword">end</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">always</span> @(<span class="keyword">posedge</span> spi_sck_rx <span class="keyword">or</span> <span class="keyword">negedge</span> rstn_spi)</span><br><span class="line"><span class="keyword">begin</span></span><br><span class="line">    <span class="keyword">if</span>(!rstn_spi) <span class="keyword">begin</span></span><br><span class="line">        rx_byte_cnt_ff &lt;= <span class="number">4&#x27;h0</span>;</span><br><span class="line">    <span class="keyword">end</span></span><br><span class="line">    <span class="keyword">else</span> <span class="keyword">if</span>(rx_byte_done &amp;&amp; (rx_byte_cnt_ff != <span class="number">4&#x27;hF</span>)) <span class="keyword">begin</span></span><br><span class="line">        rx_byte_cnt_ff &lt;= rx_byte_cnt_ff + <span class="number">4&#x27;h1</span>;</span><br><span class="line">    <span class="keyword">end</span></span><br><span class="line"><span class="keyword">end</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">assign</span> rx_first_byte = rx_byte_cnt_ff == <span class="number">4&#x27;h0</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">always</span> @(<span class="keyword">posedge</span> spi_sck_rx <span class="keyword">or</span> <span class="keyword">negedge</span> rstn_spi)</span><br><span class="line"><span class="keyword">begin</span></span><br><span class="line">    <span class="keyword">if</span>(!rstn_spi) <span class="keyword">begin</span></span><br><span class="line">        rx_shift_ff &lt;= <span class="number">8&#x27;h00</span>;</span><br><span class="line">    <span class="keyword">end</span></span><br><span class="line">    <span class="keyword">else</span> <span class="keyword">begin</span></span><br><span class="line">        rx_shift_ff &lt;= rx_shift_nx;</span><br><span class="line">    <span class="keyword">end</span></span><br><span class="line"><span class="keyword">end</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">assign</span> rx_shift_nx =</span><br><span class="line">        ((ctrl_rx_speed==spiSpeedQPI) ? &#123;rx_shift_ff[<span class="number">3</span>:<span class="number">0</span>], spi_hold_in, spi_wpn_in, spi_miso_in, spi_mosi_in&#125; : <span class="number">8&#x27;h00</span>) |</span><br><span class="line">        ((ctrl_rx_speed==spiSpeedDPI) ? &#123;rx_shift_ff[<span class="number">5</span>:<span class="number">0</span>],                          spi_miso_in, spi_mosi_in&#125; : <span class="number">8&#x27;h00</span>) |</span><br><span class="line">        ((ctrl_rx_speed==spiSpeedSPI) ? &#123;rx_shift_ff[<span class="number">6</span>:<span class="number">0</span>],                                       spi_mosi_in&#125; : <span class="number">8&#x27;h00</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">always</span> @(<span class="keyword">posedge</span> spi_sck_rx <span class="keyword">or</span> <span class="keyword">negedge</span> rstn_spi)</span><br><span class="line"><span class="keyword">begin</span></span><br><span class="line">    <span class="keyword">if</span>(!rstn_spi) <span class="keyword">begin</span></span><br><span class="line">        rx_data_f1      &lt;= <span class="number">8&#x27;h00</span>;</span><br><span class="line">        rx_byte_done_f1 &lt;= <span class="number">1&#x27;h0</span>;</span><br><span class="line">    <span class="keyword">end</span></span><br><span class="line">    <span class="keyword">else</span> <span class="keyword">if</span>(rx_byte_done) <span class="keyword">begin</span></span><br><span class="line">        rx_data_f1      &lt;= rx_shift_nx;</span><br><span class="line">        rx_byte_done_f1 &lt;= <span class="number">1&#x27;h1</span>;</span><br><span class="line">    <span class="keyword">end</span></span><br><span class="line">    <span class="keyword">else</span> <span class="keyword">begin</span></span><br><span class="line">        rx_byte_done_f1 &lt;= <span class="number">1&#x27;h0</span>;</span><br><span class="line">    <span class="keyword">end</span></span><br><span class="line"><span class="keyword">end</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">assign</span> rx_cnt_vld_mask = (ctrl_rx_speed==spiSpeedDPI) ? <span class="number">3&#x27;b001</span> : (ctrl_rx_speed==spiSpeedQPI) ? <span class="number">3&#x27;b011</span> : <span class="number">3&#x27;b000</span>;</span><br><span class="line"><span class="keyword">assign</span> rx_byte_done = (rx_cnt_ff | rx_cnt_vld_mask) == <span class="number">3&#x27;b111</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">//锁存命令</span></span><br><span class="line"><span class="keyword">always</span> @(<span class="keyword">posedge</span> spi_sck_rx <span class="keyword">or</span> <span class="keyword">negedge</span> rstn_spi)</span><br><span class="line"><span class="keyword">begin</span></span><br><span class="line">    <span class="keyword">if</span>(!rstn_spi) <span class="keyword">begin</span></span><br><span class="line">        rx_latch_cmd_ff &lt;= <span class="number">8&#x27;h00</span>;</span><br><span class="line">    <span class="keyword">end</span></span><br><span class="line">    <span class="keyword">else</span> <span class="keyword">if</span>(rx_first_byte &amp;&amp; rx_byte_done) <span class="keyword">begin</span></span><br><span class="line">        rx_latch_cmd_ff &lt;= rx_shift_nx;</span><br><span class="line">    <span class="keyword">end</span></span><br><span class="line"><span class="keyword">end</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//进入/退出 QPI 模式</span></span><br><span class="line"><span class="keyword">always</span> @(<span class="keyword">posedge</span> spi_sck_rx <span class="keyword">or</span> <span class="keyword">negedge</span> rstn)</span><br><span class="line"><span class="keyword">begin</span></span><br><span class="line">    <span class="keyword">if</span>(!rstn) <span class="keyword">begin</span></span><br><span class="line">        qpi_en_ff &lt;= <span class="number">1&#x27;h0</span>;</span><br><span class="line">    <span class="keyword">end</span></span><br><span class="line">    <span class="keyword">else</span> <span class="keyword">if</span>(!rx_first_byte || !rx_byte_done) <span class="keyword">begin</span></span><br><span class="line">        qpi_en_ff &lt;= <span class="number">1&#x27;h0</span>;</span><br><span class="line">    <span class="keyword">end</span></span><br><span class="line">    <span class="keyword">else</span> <span class="keyword">if</span>(!qpi_en_ff &amp;&amp; (rx_shift_nx==instEQIO)) <span class="keyword">begin</span></span><br><span class="line">        qpi_en_ff &lt;= <span class="number">1&#x27;h1</span>;</span><br><span class="line">    <span class="keyword">end</span></span><br><span class="line">    <span class="keyword">else</span> <span class="keyword">if</span>(rx_shift_nx==instRstQIO) <span class="keyword">begin</span></span><br><span class="line">        qpi_en_ff &lt;= <span class="number">1&#x27;h0</span>;</span><br><span class="line">    <span class="keyword">end</span></span><br><span class="line"><span class="keyword">end</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//有些控制信号会在CS 拉高时维持，comm_stat_ff 表示控制信号是否在CS拉高时维持的，内部电路需要忽略</span></span><br><span class="line"><span class="keyword">always</span> @(<span class="keyword">posedge</span> spi_sck_rx <span class="keyword">or</span> <span class="keyword">negedge</span> rstn_spi)</span><br><span class="line"><span class="keyword">begin</span></span><br><span class="line">    <span class="keyword">if</span>(!rstn_spi) <span class="keyword">begin</span></span><br><span class="line">        comm_acti_ff &lt;= <span class="number">1&#x27;h0</span>;</span><br><span class="line">    <span class="keyword">end</span></span><br><span class="line">    <span class="keyword">else</span> <span class="keyword">begin</span></span><br><span class="line">        comm_acti_ff &lt;= <span class="number">1&#x27;h1</span>;</span><br><span class="line">    <span class="keyword">end</span></span><br><span class="line"><span class="keyword">end</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//SPI 输出</span></span><br><span class="line"><span class="comment">//always @(posedge spi_sck_tx or negedge rstn_spi)</span></span><br><span class="line"><span class="keyword">always</span> @(<span class="keyword">negedge</span> spi_sck_rx <span class="keyword">or</span> <span class="keyword">negedge</span> rstn_spi)</span><br><span class="line"><span class="keyword">begin</span></span><br><span class="line">    <span class="keyword">if</span>(!rstn_spi) <span class="keyword">begin</span></span><br><span class="line">        spi_holdn_oe_ff &lt;= <span class="number">1&#x27;h0</span>;</span><br><span class="line">        spi_wpn_oe_ff   &lt;= <span class="number">1&#x27;h0</span>;</span><br><span class="line">    <span class="keyword">end</span></span><br><span class="line">    <span class="keyword">else</span> <span class="keyword">if</span>(ctrl_tx_speed == spiSpeedQPI) <span class="keyword">begin</span></span><br><span class="line">        spi_holdn_oe_ff &lt;= tx_enable_ff;</span><br><span class="line">        spi_wpn_oe_ff   &lt;= tx_enable_ff;</span><br><span class="line">    <span class="keyword">end</span></span><br><span class="line">    <span class="keyword">else</span> <span class="keyword">begin</span></span><br><span class="line">        spi_holdn_oe_ff &lt;= <span class="number">1&#x27;h0</span>;</span><br><span class="line">        spi_wpn_oe_ff   &lt;= <span class="number">1&#x27;h0</span>;</span><br><span class="line">    <span class="keyword">end</span></span><br><span class="line"><span class="keyword">end</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//always @(posedge spi_sck_tx or negedge rstn_spi)</span></span><br><span class="line"><span class="keyword">always</span> @(<span class="keyword">negedge</span> spi_sck_rx <span class="keyword">or</span> <span class="keyword">negedge</span> rstn_spi)</span><br><span class="line"><span class="keyword">begin</span></span><br><span class="line">    <span class="keyword">if</span>(!rstn_spi) <span class="keyword">begin</span></span><br><span class="line">        spi_miso_oe_ff &lt;= <span class="number">1&#x27;h0</span>;</span><br><span class="line">        spi_mosi_oe_ff &lt;= <span class="number">1&#x27;h0</span>;</span><br><span class="line">    <span class="keyword">end</span></span><br><span class="line">    <span class="keyword">else</span> <span class="keyword">if</span>(ctrl_tx_speed == spiSpeedSPI) <span class="keyword">begin</span></span><br><span class="line">        spi_miso_oe_ff &lt;= <span class="number">1&#x27;h1</span>;</span><br><span class="line">        spi_mosi_oe_ff &lt;= <span class="number">1&#x27;h0</span>;</span><br><span class="line">    <span class="keyword">end</span></span><br><span class="line">    <span class="keyword">else</span> <span class="keyword">begin</span></span><br><span class="line">        spi_miso_oe_ff &lt;= tx_enable_ff;</span><br><span class="line">        spi_mosi_oe_ff &lt;= tx_enable_ff;</span><br><span class="line">    <span class="keyword">end</span></span><br><span class="line"><span class="keyword">end</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//always @(posedge spi_sck_tx or negedge rstn_spi)</span></span><br><span class="line"><span class="keyword">always</span> @(<span class="keyword">negedge</span> spi_sck_rx <span class="keyword">or</span> <span class="keyword">negedge</span> rstn_spi)</span><br><span class="line"><span class="keyword">begin</span></span><br><span class="line">    <span class="keyword">if</span>(!rstn_spi) <span class="keyword">begin</span></span><br><span class="line">        spi_holdn_out_ff &lt;= <span class="number">1&#x27;h0</span>;</span><br><span class="line">        spi_wpn_out_ff   &lt;= <span class="number">1&#x27;h0</span>;</span><br><span class="line">        spi_miso_out_ff  &lt;= <span class="number">1&#x27;h0</span>;</span><br><span class="line">        spi_mosi_out_ff  &lt;= <span class="number">1&#x27;h0</span>;</span><br><span class="line">    <span class="keyword">end</span></span><br><span class="line">    <span class="keyword">else</span> <span class="keyword">if</span>(ctrl_tx_speed == spiSpeedQPI) <span class="keyword">begin</span></span><br><span class="line">        spi_holdn_out_ff &lt;= tx_shift_ff[<span class="number">7</span>];</span><br><span class="line">        spi_wpn_out_ff   &lt;= tx_shift_ff[<span class="number">6</span>];</span><br><span class="line">        spi_miso_out_ff  &lt;= tx_shift_ff[<span class="number">5</span>];</span><br><span class="line">        spi_mosi_out_ff  &lt;= tx_shift_ff[<span class="number">4</span>];</span><br><span class="line">    <span class="keyword">end</span></span><br><span class="line">    <span class="keyword">else</span> <span class="keyword">if</span>(ctrl_tx_speed == spiSpeedQPI) <span class="keyword">begin</span></span><br><span class="line">        spi_holdn_out_ff &lt;= <span class="number">1&#x27;h0</span>;</span><br><span class="line">        spi_wpn_out_ff   &lt;= <span class="number">1&#x27;h0</span>;</span><br><span class="line">        spi_miso_out_ff  &lt;= tx_shift_ff[<span class="number">7</span>];</span><br><span class="line">        spi_mosi_out_ff  &lt;= tx_shift_ff[<span class="number">6</span>];</span><br><span class="line">    <span class="keyword">end</span></span><br><span class="line"><span class="keyword">end</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">assign</span> spi_holdn_oe  = spi_holdn_oe_ff;</span><br><span class="line"><span class="keyword">assign</span> spi_holdn_out = spi_holdn_out_ff;</span><br><span class="line"><span class="keyword">assign</span> spi_wpn_oe    = spi_wpn_oe_ff;</span><br><span class="line"><span class="keyword">assign</span> spi_wpn_out   = spi_wpn_out_ff;</span><br><span class="line"><span class="keyword">assign</span> spi_miso_oe   = spi_miso_oe_ff;</span><br><span class="line"><span class="keyword">assign</span> spi_miso_out  = spi_miso_out_ff;</span><br><span class="line"><span class="keyword">assign</span> spi_mosi_oe   = spi_mosi_oe_ff;</span><br><span class="line"><span class="keyword">assign</span> spi_mosi_out  = spi_mosi_out_ff;</span><br><span class="line"></span><br><span class="line"><span class="keyword">assign</span> stat_comm_acti = comm_acti_ff;</span><br><span class="line"><span class="keyword">assign</span> stat_qpi_en    = qpi_en_ff;</span><br><span class="line"><span class="keyword">assign</span> stat_spi_cmd   = rx_latch_cmd_ff;</span><br><span class="line"></span><br><span class="line"><span class="keyword">assign</span> trx_tx_valid   = tx_set_nx_byte;</span><br><span class="line"><span class="keyword">assign</span> trx_tx_bytes   = rx_byte_cnt_ff;</span><br><span class="line"></span><br><span class="line"><span class="keyword">assign</span> trx_rx_valid   = rx_byte_done_f1;</span><br><span class="line"><span class="keyword">assign</span> trx_rx_bytes   = rx_byte_cnt_ff;</span><br><span class="line"><span class="keyword">assign</span> trx_rx_data    = rx_data_f1;</span><br><span class="line"></span><br><span class="line"><span class="keyword">assign</span> spi_rx_bit_cnt = rx_cnt_ff;</span><br><span class="line"><span class="keyword">assign</span> spi_rx_data    = rx_shift_ff;</span><br><span class="line"></span><br><span class="line"><span class="keyword">endmodule</span></span><br></pre></td></tr></table></figure>

<h1 id="6-端口约束"><a href="#6-端口约束" class="headerlink" title="6. 端口约束"></a>6. 端口约束</h1>
      
    </div>
    <footer class="article-footer">
      <a data-url="https://linkliao610.gitee.io/2025/03/12/Protocol-Series-SPI-0/" data-id="cm88s0iv10000mwux7ujt7xn9" data-title="SPI从收发器电路设计" class="article-share-link"><span class="fa fa-share">Share</span></a>
      
      
      
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/SPI/" rel="tag">SPI</a></li></ul>

    </footer>
  </div>
  
</article>



  
    <article id="post-Protocol-Series-EtherCAT-0" class="h-entry article article-type-post" itemprop="blogPost" itemscope itemtype="https://schema.org/BlogPosting">
  <div class="article-meta">
    <a href="/2025/03/12/Protocol-Series-EtherCAT-0/" class="article-date">
  <time class="dt-published" datetime="2025-03-12T02:12:24.000Z" itemprop="datePublished">2025-03-12</time>
</a>
    
  <div class="article-category">
    <a class="article-category-link" href="/categories/Protocol/">Protocol</a>
  </div>

  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="p-name article-title" href="/2025/03/12/Protocol-Series-EtherCAT-0/">EtherCAT 协议(0)</a>
    </h1>
  

      </header>
    
    <div class="e-content article-entry" itemprop="articleBody">
      
        <h1 id="1-介绍"><a href="#1-介绍" class="headerlink" title="1. 介绍"></a>1. 介绍</h1><p>EtherCAT（Ethernet for Control Automation Technology）是一种高性能的实时工业以太网通信协议，由德国Beckhoff自动化公司于2003年开发，并在2014年成为国际标准（IEC 61158-12）。它专为工业自动化和控制领域设计，旨在实现高实时性、高效率和低成本的通信</p>
<p>EtherCAT的参考资料如下：</p>
<ul>
<li><a target="_blank" rel="noopener" href="https://download.beckhoff.com/download/document/io/ethercat-development-products/ethercat_esc_datasheet_sec1_technology_2i3.pdf">EtherCAT Slave Controller Hardware Data Sheet Section I-Technology</a></li>
<li><a target="_blank" rel="noopener" href="https://download.beckhoff.com/download/document/io/ethercat-development-products/ethercat_esc_datasheet_sec2_registers_3i0.pdf">EtherCAT Slave Controller Hardware Data Sheet Section II-Register Descritpion</a></li>
<li><a target="_blank" rel="noopener" href="https://download.beckhoff.com/download/document/io/ethercat-development-products/ethercat_et1100_datasheet_v2i1.pdf">EtherCAT Slave Controller Hardware Data Sheet Section III-Hardware Description of ET1100</a></li>
<li><a target="_blank" rel="noopener" href="https://download.beckhoff.com/download/document/io/ethercat-development-products/ethercat_et1200_datasheet_v2i2.pdf">EtherCAT Slave Controller Hardware Data Sheet Section III-Hardware Description of ET1200</a></li>
</ul>
<p>此外，EtherCAT技术协会 ETG(EtherCAT Technology Group) 推出了相应的文档定义了EtherCAT标准：</p>
<ul>
<li>ETG.1000.1: 概述</li>
<li>ETG.1000.2: 物理层服务定义和协议规范</li>
<li>ETG.1000.3：数据链路层服务定义</li>
<li>ETG.1000.4: 数据链路层协议规范</li>
<li>ETG.1000.5: 应用层服务定义</li>
<li>ETG.1000.6: 应用层协议规范</li>
</ul>
<h1 id="2-EtherCAT-协议"><a href="#2-EtherCAT-协议" class="headerlink" title="2.EtherCAT 协议"></a>2.EtherCAT 协议</h1><p>EtherCAT 是一种基于以太网的现场总线技术，使用了IEEE 802.3以太网标准数据帧，并将EtherType设置为0x88A4用于区分其他以太网数据帧，因此，EtherCAT 可以跟其他以太网协议并行运行。</p>
<p>包含EtherCAT数据的以太网数据帧格式如下图所示</p>
<p><img src="/2025/03/12/Protocol-Series-EtherCAT-0/Figure1_EthernetFrameWithEtherCATData.png" alt="Figure 1 Ethernet Frame with EtherHeader"></p>
<p>EtherCAT数据帧以2字节的帧头开始，EtherCAT数据帧头格式如下表所示：</p>
<table>
<thead>
<tr>
<th align="left">域</th>
<th align="left">数据类型</th>
<th align="left">数值&#x2F;描述</th>
</tr>
</thead>
<tbody><tr>
<td align="left">Length</td>
<td align="left">11 bit</td>
<td align="left">EtherCAT 数据帧的长度(FCS 除外)</td>
</tr>
<tr>
<td align="left">Reserved</td>
<td align="left">1 bit</td>
<td align="left">保留，0</td>
</tr>
<tr>
<td align="left">Type</td>
<td align="left">4 bit</td>
<td align="left">协议类型，从站只支持Type&#x3D;1的EtherCAT命令</td>
</tr>
</tbody></table>
<h1 id="3-EtherCAT-数据帧"><a href="#3-EtherCAT-数据帧" class="headerlink" title="3.EtherCAT 数据帧"></a>3.EtherCAT 数据帧</h1>
      
    </div>
    <footer class="article-footer">
      <a data-url="https://linkliao610.gitee.io/2025/03/12/Protocol-Series-EtherCAT-0/" data-id="cm88s0iv70005mwux805bdk1f" data-title="EtherCAT 协议(0)" class="article-share-link"><span class="fa fa-share">Share</span></a>
      
      
      
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/EtherCAT/" rel="tag">EtherCAT</a></li></ul>

    </footer>
  </div>
  
</article>



  


</section>
        
          <aside id="sidebar">
  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Categories</h3>
    <div class="widget">
      <ul class="category-list"><li class="category-list-item"><a class="category-list-link" href="/categories/Protocol/">Protocol</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Tags</h3>
    <div class="widget">
      <ul class="tag-list" itemprop="keywords"><li class="tag-list-item"><a class="tag-list-link" href="/tags/EtherCAT/" rel="tag">EtherCAT</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/SPI/" rel="tag">SPI</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Tag Cloud</h3>
    <div class="widget tagcloud">
      <a href="/tags/EtherCAT/" style="font-size: 10px;">EtherCAT</a> <a href="/tags/SPI/" style="font-size: 10px;">SPI</a>
    </div>
  </div>

  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Archives</h3>
    <div class="widget">
      <ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/archives/2025/03/">March 2025</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Recent Posts</h3>
    <div class="widget">
      <ul>
        
          <li>
            <a href="/2025/03/12/Protocol-Series-SPI-0/">SPI从收发器电路设计</a>
          </li>
        
          <li>
            <a href="/2025/03/12/Protocol-Series-EtherCAT-0/">EtherCAT 协议(0)</a>
          </li>
        
      </ul>
    </div>
  </div>

  
</aside>
        
      </div>
      <footer id="footer">
  
  <div class="outer">
    <div id="footer-info" class="inner">
      
      &copy; 2025 LinkLiao<br>
      Powered by <a href="https://hexo.io/" target="_blank">Hexo</a>
    </div>
  </div>
</footer>

    </div>
    <nav id="mobile-nav">
  
    <a href="/" class="mobile-nav-link">Home</a>
  
    <a href="/archives" class="mobile-nav-link">Archives</a>
  
</nav>
    


<script src="/js/jquery-3.6.4.min.js"></script>



  
<script src="/fancybox/jquery.fancybox.min.js"></script>




<script src="/js/script.js"></script>





  </div>
</body>
</html>